
// 接口
interface R{
    a?: number;//可选
    b?: string;
    c: number;//必选
    d?: string;
    nums?: number;
    m?: string;
}

// 1. Partial<T>：将类型的所有属性转为可选
type P = Partial<R>; 
let p1: P = { a: 200 }; 
let p2: P = { b: "400", c: 300};
console.log("P:",p1)

// 2. Required<T>：将类型的所有属性转为必选
type Re = Required<R>;
let res: Re = { a: 200, b: "完", c:400,d: "成",nums:300,m:"test" };
console.log("Re:", res);

// 3. Pick<T, K>：会从T中提取K(K是T的属性名)，形成新类型
type Pi = Pick<R, "a" | "b">;
let pi: Pi = { a: 200, b: "新的" };
console.log("Pi:",pi);

// 4. Omit<T, K>：从T中排除为K,留下别的
type O = Omit<R, "m">;
let o: O = { a: 200, b: "无", c: 200 };
console.log("O:", o);

// 5. Readonly：让 T 中所有属性变为只读（无法修改）
type Ro = Readonly<R>;
let ro: Ro = { a: 200, d: "读", c: 200 };
console.log("Ro:", ro);

// 6. ReturnType<T>：获取函数 T 的返回值类型
function f(): R { return { nums: 200, d: "接", c: 200 }; }
type Ft = ReturnType<typeof f>;
let ft: Ft = { nums: 200, d: "配", c: 200 };
console.log("Ft:", ft);

// 8. Record<K, T>：定义一个对象类型，其中键的类型是 K，值的类型是 T
// 键是 string 类型，值是 R 类型
type Rm = Record<string, R>;
let rm: Rm = {
  ok: { nums: 200, d: "成", c: 200 },
  no: { nums: 500, d: "败", c: 500, m: "错" }
};
// 键只能是 "ok" 或 "no"（联合类型），值是 R 类型
type K = "ok" | "no";
type Lr = Record<K, R>;
let lr: Lr = {
  ok: { nums: 200, d: "ok", c: 200 },
  no: { nums: 400, d: "no", c: 400 }
};
console.log("Rm:", rm);
console.log("Lr:", lr);

// 9. Exclude：排除联合类型
type Ct = R["c"];
type Sc = Exclude<Ct, 400 | 500>;
let sc: Sc = 200;
console.log("Sc:", sc);

// 10. Parameters：参数类型
function h(r: R, m: string) { console.log("处:", r.d, m); }
type Hp = Parameters<typeof h>;
let hp: Hp = [{ nums: 200, d: "参", c: 200 }, "成"];
h(...hp);

// 组合用法
type C = Readonly<Partial<Pick<R, "nums" | "c">>>;
let c: C = { nums: 200 };
console.log("组合:", c);